package com.autumn.platform.web.request;

import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;

import com.autumn.platform.core.context.token.Token;
import com.autumn.platform.core.context.token.TokenHolder;
import com.autumn.platform.core.logger.Logs;

public class CompositeHttpSessionIdResolver implements HttpSessionIdResolver {

    public static final String TOKEN_PARAM_NAME = "_token";

    public static final String TOKEN_HEADER_NAME = "X-Auth-Token";

    private static final HttpSessionIdResolver cookie = new CookieHttpSessionIdResolver();

    private String paramName = TOKEN_PARAM_NAME;

    private String headerName = TOKEN_HEADER_NAME;

    private boolean enableParam = true;

    private boolean enableHeader = true;

    @Override
    public List<String> resolveSessionIds(HttpServletRequest request) {
        String value = null;
        if (this.isEnableHeader()) {
            value = request.getHeader(this.headerName);
            if (null != value) {
                Logs.trace("resolve token from request header [" + value + "]");
            }
        }
        if (null == value && this.isEnableParam() && null != this.paramName) {
            value = request.getParameter(this.paramName);
            if (null != value) {
                Logs.trace("resolve token from request param [" + value + "]");
            }
        }
        if (value != null) {
            Token token = TokenHolder.verifyToken(value);
            if (null != token) {
                Logs.trace("resolve session id [" + token.getExtendedInformation() + "] from token [" + value + "]");
                return Collections.singletonList(token.getExtendedInformation());
            } else {
                Logs.warn("resolve session id is null from token [" + value + "]");
            }
        }

        List<String> ids = cookie.resolveSessionIds(request);
        if (null != ids && !ids.isEmpty()) {
            for (String sessionId : ids) {
                Logs.trace("resolve session id from cookie [" + sessionId + "]");
            }
            return ids;
        }
        return Collections.emptyList();
    }

    @Override
    public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
        cookie.setSessionId(request, response, sessionId);
    }

    @Override
    public void expireSession(HttpServletRequest request, HttpServletResponse response) {
        cookie.expireSession(request, response);
        if (this.isEnableHeader()) {
            response.setHeader(this.headerName, "");
        }
    }

    public void setParamName(String paramName) {
        this.paramName = paramName;
    }

    public void setHeaderName(String headerName) {
        this.headerName = headerName;
    }

    public boolean isEnableParam() {
        return enableParam;
    }

    public void setEnableParam(boolean enableParam) {
        this.enableParam = enableParam;
    }

    public boolean isEnableHeader() {
        return enableHeader;
    }

    public void setEnableHeader(boolean enableHeader) {
        this.enableHeader = enableHeader;
    }
}
